using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.IMGUI.Controls;
using UnityEditor;
using UnityEngine;
using System;


namespace LS.Editor.Tool
{

    /// <summary>
    /// 绘制列元素的方法
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="cellRect">绘制区域</param>
    /// <param name="data">绘制数据</param>
    /// <param name="rowIndex">在表格中的行索引</param>
    /// <param name="isSelected">是否选中</param>
    /// <param name="isFocused">是否焦点</param>
    public delegate void DrawCellMethod<T>(Rect cellRect, T data, int rowIndex, bool isSelected, bool isFocused);

    /// <summary>
    /// 对比列元素的方法
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="data1">数据1</param>
    /// <param name="data2">数据2</param>
    /// <returns>排序号</returns>
    public delegate int CompareMethod<T>(T data1, T data2);

    /// <summary>
    /// 头部被修改的回调
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="data"></param>
    /// <param name="text"></param>
    /// <param name="previous"></param>
    public delegate void DrawColumnHeaderCallback(MultiColumnHeaderState.Column column, Rect headerRect, int columnIndex);

    /// <summary>
    /// 表格视图列元素
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    public class TableColumn : MultiColumnHeaderState.Column
    {
        public virtual int ColumnId { get; }
        /// <summary>
        /// 绘制列元素的方法
        /// </summary>
        public DrawCellMethod<TableViewItem> DrawCell;
        /// <summary>
        /// 对比列元素的方法
        /// </summary>
        public CompareMethod<TableViewItem> Compare;

        public bool Equals(TableColumn obj)
        {
            return this.GetHashCode() == obj.GetHashCode() ||
                obj.headerContent == this.headerContent ||
                (!string.IsNullOrEmpty(this.headerContent.text) && headerContent.text == obj.headerContent.text) ||
                (headerContent.image != null && headerContent.image == obj.headerContent.image);
        }
    }

    public abstract class TableViewItem: TreeViewItem
    {
        protected static int s_IdMark = 0;
        protected bool m_Disable;
        protected bool m_Modifiable;

        public bool Disable
        {
            get
            {
                return m_Disable;
            }

            set
            {
                m_Disable = value;
            }
        }

        public bool Modifiable
        {
            get
            {
                return m_Modifiable;
            }

            set
            {
                m_Modifiable = value;
            }
        }

        public abstract Type DataType { get; }
        public abstract object RowData { get; }
        public abstract void DrawItemGui(Rect rect, TableColumn column, bool isSelected, bool isFocused);
        public TableViewItem(int id, int depth,string displayName,bool disable = false,bool modifiable = true): base(id, depth, displayName)
        {
            m_Disable = disable;
            m_Modifiable = modifiable;
        }
    }

    /// <summary>
    /// 表格视图元素
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    public abstract class TableViewItem<T> : TableViewItem where T : class, new()
    {
        private Type m_DataType = null;
        protected T m_Data = null;
        /// <summary>
        /// 元素的数据
        /// </summary>
        public T Data
        {
            get
            {
                return m_Data;
            }
        }

        public override object RowData
        {
            get
            {
                return Data;
            }
        }

        public override Type DataType
        {
            get
            {
                return m_DataType;
            }
        }

        public TableViewItem(int id, int depth, T data, string displayName = "Content") : base(data?.GetHashCode()?? s_IdMark++, depth, displayName)
        {
            m_Data = data;

            if (data != null)
                m_DataType = data.GetType();
            else
                m_DataType = typeof(T);
        }
    }

    /// <summary>
    /// 表格视图
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    public sealed class TableView : TreeView
    {

        /// <summary>
        /// 所有的元素
        /// </summary>
        private List<TableViewItem> m_Items;

        /// <summary>
        /// 当前选择的表格数据
        /// </summary>
        private List<TableViewItem> m_SelectionDatas;

        /// <summary>
        /// 根元素
        /// </summary>
        private TableViewItem m_RootItem;

        /// <summary>
        /// 所有的头部元素
        /// </summary>
        private List<TableColumn> m_HeaderColumns;

        /// <summary>
        /// 用于绘制的元素
        /// </summary>
        private List<TreeViewItem> m_DrawItems;

        /// <summary>
        /// 搜索控件
        /// </summary>
        private SearchField m_SearchField;

        /// <summary>
        /// 当选择项改变
        /// </summary>
        public event Action<TreeViewItem[]> OnSelectionChanged;

        /// <summary>
        /// 右键点击上下文时
        /// </summary>
        public Action<TreeViewItem[]> OnContextClicked;

        /// <summary>
        /// 搜索数据时的方法
        /// </summary>
        public Func<TreeViewItem, string, bool> OnSearch;

        /// <summary>
        /// 计算行高度的方法
        /// </summary>
        public Func<int, TreeViewItem, float> GetRowHeightFunc;

        /// <summary>
        /// 行高度
        /// </summary>
        public float RowHeight
        {
            get
            {
                return rowHeight;
            }
            set
            {
                rowHeight = value;
            }
        }
        /// <summary>
        /// 是否启用上下文右键点击
        /// </summary>
        public bool IsEnableContextClick { get; set; } = true;
        /// <summary>
        /// 是否允许多选
        /// </summary>
        public bool IsCanMultiSelect { get; set; } = true;
        /// <summary>
        /// 是否启用搜索框
        /// </summary>
        public bool IsEnableSearch { get; set; } = false;

        /// <summary>
        /// 列数
        /// </summary>
        public int ColumnCount => m_HeaderColumns.Count;

        /// <summary>
        /// 已添加的元素数量
        /// </summary>
        public int ItemCount => m_HeaderColumns.Count;

        /// <summary>
        /// 返回当前所有列对象
        /// </summary>
        public TableColumn[] Columns => m_HeaderColumns.ToArray();

        /// <summary>
        /// 返回所有内容对象
        /// </summary>
        public TableViewItem[] Items => m_Items.ToArray();

        /// <summary>
        /// 表格视图
        /// </summary>
        /// <param name="datas">表格视图数据</param>
        /// <param name="columns">表格视图的所有列</param>
        public TableView(TableColumn[] columns = null, TableViewItem[] datas = null) : base(new TreeViewState())
        {
            m_RootItem = new RootTableViewItem();
            m_SearchField = new SearchField();
            m_SelectionDatas = new List<TableViewItem>();
            m_Items = new List<TableViewItem>();
            m_HeaderColumns = new List<TableColumn>();
            m_DrawItems = new List<TreeViewItem>();

            if (columns != null && columns.Length > 0)
                m_HeaderColumns.AddRange(columns);

            showAlternatingRowBackgrounds = true;
            showBorder = true;
            rowHeight = EditorGUIUtility.singleLineHeight + 4;

            if (columns == null)
                columns = new TableColumn[0];

            multiColumnHeader = new MultiColumnHeader(new MultiColumnHeaderState(columns));
            multiColumnHeader.sortingChanged += OnSortingChanged;
            multiColumnHeader.visibleColumnsChanged += OnVisibleColumnsChanged;

            AddItem(datas);
            Reload();
        }
        /// <summary>
        /// 构造根节点
        /// </summary>
        protected override TreeViewItem BuildRoot()
        {
            return m_RootItem;
        }

        protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
        {
            m_DrawItems.Clear();
            for (int i = 0; i < m_Items.Count; i++)
            {
                Internal_AddDrawItemsAndChildren(m_Items[i]);
            }
            return m_DrawItems;
        }

        /// <summary>
        /// 绘制行
        /// </summary>
        protected override void RowGUI(RowGUIArgs args)
        {
            TableViewItem item = args.item as TableViewItem;
            int visibleColumns = args.GetNumVisibleColumns();
            for (var i = 0; i < visibleColumns; i++)
            {
                Rect cellRect = args.GetCellRect(i);
                int index = args.GetColumn(i);
                CenterRectUsingSingleLineHeight(ref cellRect);
                TableColumn column = multiColumnHeader.GetColumn(index) as TableColumn;
                column.DrawCell?.Invoke(cellRect, item, args.row, args.selected, args.focused);
            }
        }

        /// <summary>
        /// 上下文右键点击
        /// </summary>
        protected override void ContextClicked()
        {
            if (!IsEnableContextClick)
                return;

            OnContextClicked?.Invoke(m_SelectionDatas.ToArray());
        }

        /// <summary>
        /// 当选择项改变
        /// </summary>
        protected override void SelectionChanged(IList<int> selectedIds)
        {
            base.SelectionChanged(selectedIds);

            m_SelectionDatas.Clear();
            foreach (var itemID in selectedIds)
            {
                TableViewItem item = m_Items.Find((it) => { return it.id == itemID; });
                if (item != null) m_SelectionDatas.Add(item);
            }

            OnSelectionChanged?.Invoke(m_SelectionDatas.ToArray());
        }
        /// <summary>
        /// 是否允许多选
        /// </summary>
        protected override bool CanMultiSelect(TreeViewItem item)
        {
            return IsCanMultiSelect;
        }

        /// <summary>
        /// 绘制表格视图
        /// </summary>
        /// <param name="rect">绘制区域</param>
        public override void OnGUI(Rect rect)
        {
            if (IsEnableSearch)
            {
                Rect sub = new Rect(rect.x, rect.y, 60, 16);
                EditorGUI.LabelField(sub, "Search: ");
                sub.Set(rect.x + 60, rect.y, rect.width - 60, 18);
                searchString = m_SearchField.OnGUI(sub, searchString);

                rect.y += 18;
                rect.height -= 18;
                base.OnGUI(rect);
            }
            else
            {
                base.OnGUI(rect);
            }
        }

        /// <summary>
        /// 当重新排序
        /// </summary>
        private void OnSortingChanged(MultiColumnHeader columnheader)
        {
            bool isAscending = multiColumnHeader.IsSortedAscending(multiColumnHeader.sortedColumnIndex);
            TableColumn column = multiColumnHeader.GetColumn(multiColumnHeader.sortedColumnIndex) as TableColumn;
            if (column.Compare != null)
            {
                m_Items.Sort((a, b) =>
                {
                    if (isAscending)
                    {
                        return -column.Compare(a, b);
                    }
                    else
                    {
                        return column.Compare(a, b);
                    }
                });
                Reload();
            }
        }
        /// <summary>
        /// 当列激活状态改变
        /// </summary>
        private void OnVisibleColumnsChanged(MultiColumnHeader columnheader)
        {
            Reload();
        }

        /// <summary>
        /// 添加列
        /// </summary>
        /// <param name="column"></param>
        public void AddColumn(TableColumn column)
        {
            int index = m_HeaderColumns.FindIndex(c => c.Equals(column));
            if (index >= 0)
            {
                Debug.LogWarning($"Column {column.headerContent.ToString()} is exist !");
                return;
            }
            m_HeaderColumns.Add(column);
            multiColumnHeader.state = new MultiColumnHeaderState(m_HeaderColumns.ToArray());
            //Reload();
        }

        /// <summary>
        /// 添加列
        /// </summary>
        /// <param name="column"></param>
        public void AddColumn(TableColumn[] column)
        {
            for (int i = 0; i < column.Length; i++)
            {
                int index = m_HeaderColumns.FindIndex(c => c.Equals(column[i]));
                if (index >= 0)
                {
                    Debug.LogWarning($"Column {column[i].headerContent.ToString()} is exist !");
                    continue;
                }

                m_HeaderColumns.Add(column[i]);
            }
            multiColumnHeader.state = new MultiColumnHeaderState(m_HeaderColumns.ToArray());
            //Reload();
        }

        /// <summary>
        /// 移除列
        /// </summary>
        /// <param name="column"></param>
        public void RemoveColumn(TableColumn column)
        {
            int index = m_HeaderColumns.FindIndex(c => c.Equals(column));
            if (index < 0)
            {
                return;
            }
            m_HeaderColumns.RemoveAt(index);
            multiColumnHeader.state = new MultiColumnHeaderState(m_HeaderColumns.ToArray());
            //Reload();
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="item">数据</param>
        public void AddItem(TableViewItem item)
        {
            if (m_Items.Contains(item))
                return;

            Internal_AddItem(item);

            //Reload();
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="items">数据</param>
        public void AddItem(List<TableViewItem> items)
        {
            for (int i = 0; i < items.Count; i++)
            {
                TableViewItem item = items[i];
                if (m_Items.Contains(item))
                    continue;

                Internal_AddItem(item);
            }
            //Reload();
        }

        public void AddItem(TableViewItem[] items)
        {
            if (items == null || items.Length == 0)
                return;

            for (int i = 0; i < items.Length; i++)
            {
                TableViewItem item = items[i];
                if (m_Items.Contains(item))
                    continue;

                Internal_AddItem(item);
            }
            //Reload();
        }

        public void AddItemAt(TableViewItem item,int index)
        {
            if (m_Items.Contains(item))
                return;

            Internal_AddItemAt(item,index);

        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="item">数据</param>
        public void DeleteItem(TableViewItem item)
        {
            if (!m_Items.Contains(item))
                return;

            Internal_RemoveItem(item);
            //Reload();
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="datas">数据</param>
        public void DeleteItems(List<TableViewItem> items)
        {
            for (int i = 0; i < items.Count; i++)
            {
                TableViewItem item = items[i];
                if (!m_Items.Contains(item))
                    continue;

                Internal_RemoveItem(item);
            }
            //Reload();
        }

        /// <summary>
        /// 选中数据
        /// </summary>
        /// <param name="data">数据</param>
        public void SelectItem(TableViewItem item)
        {
            if (!m_Items.Contains(item))
                return;

            if (item != null)
            {
                SetSelection(new int[] { item.id });
            }
        }

        /// <summary>
        /// 选中数据
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="options">选中的操作</param>
        public void SelectItem(TableViewItem item, TreeViewSelectionOptions options)
        {
            if (!m_Items.Contains(item))
                return;

            if (item != null)
            {
                SetSelection(new int[] { item.id }, options);
            }
        }

        /// <summary>
        /// 选中数据
        /// </summary>
        /// <param name="items">数据</param>
        public void SelectItems(List<TableViewItem> items)
        {
            List<int> ids = new List<int>();
            for (int i = 0; i < items.Count; i++)
            {
                TableViewItem item = items[i];
                if (!m_Items.Contains(item))
                    continue;

                if (item != null)
                {
                    ids.Add(item.id);
                }
            }

            if (ids.Count > 0)
            {
                SetSelection(ids);
            }
        }

        /// <summary>
        /// 选中数据
        /// </summary>
        /// <param name="datas">数据</param>
        /// <param name="options">选中的操作</param>
        public void SelectItems(List<TableViewItem> items, TreeViewSelectionOptions options)
        {
            List<int> ids = new List<int>();
            for (int i = 0; i < items.Count; i++)
            {
                TableViewItem item = items[i];
                if (!m_Items.Contains(item))
                    continue;

                if (item != null)
                {
                    ids.Add(item.id);
                }
            }

            if (ids.Count > 0)
            {
                SetSelection(ids, options);
            }
        }

        /// <summary>
        /// 选中数据
        /// </summary>
        /// <param name="datas">数据</param>
        /// <param name="options">选中的操作</param>
        public void SelectItems(TableViewItem[] items, TreeViewSelectionOptions options = TreeViewSelectionOptions.None)
        {
            List<int> ids = new List<int>();
            for (int i = 0; i < items.Length; i++)
            {
                TableViewItem item = items[i];
                if (!m_Items.Contains(item))
                    continue;

                if (item != null)
                {
                    ids.Add(item.id);
                }
            }

            if (ids.Count > 0)
            {
                SetSelection(ids, options);
            }
        }

        /// <summary>
        /// 清空所有数据
        /// </summary>
        public void ClearItems()
        {
            m_Items.Clear();
            //Reload();
        }

        public void ClearColump()
        {
            m_HeaderColumns.Clear();
            //Reload();
        }

        private void Internal_AddItemAt(TableViewItem item,int index)
        {
            if (!m_Items.Contains(item))
                m_Items.Insert(index, item);
            
        }

        private void Internal_AddItem(TableViewItem item)
        {
            if(!m_Items.Contains(item))
                m_Items.Add(item);
        }

        private void Internal_RemoveItem(TableViewItem item)
        {
            m_Items.Remove(item);
        }

        private void Internal_AddDrawItemsAndChildren(TreeViewItem item)
        {
            if (hasSearch && OnSearch != null)
            {
                if (OnSearch(item, searchString))
                    m_DrawItems.Add(item);
            }
            else
            {
                m_DrawItems.Add(item);
            }

            if (item.hasChildren)
            {
                for (int i = 0; i < item.children.Count; i++)
                {
                    var child = item.children[i];
                    Internal_AddDrawItemsAndChildren(child);
                }
            }
        }

        private class RootTableViewItem : TableViewItem<object>
        {
            public RootTableViewItem() : base(-1, -1, null, "Root")
            {
            }

            public override void DrawItemGui(Rect rect, TableColumn column, bool isSelected, bool isFocused)
            {
                
            }
        }
    }
}
